#include <algorithm>
#include <cstdio>

typedef long long ll;
const int N = 305;
int n;
ll sum[N], f[N][N][2];
bool vis[N][N][2], mgcd[N][N];

struct Node {
  ll k, v;
  inline bool operator<(const Node &rhs) const { return k < rhs.k; }
} a[N];

ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }

inline void max(ll &a, const ll &b) {
  if (a < b) a = b;
}

inline ll solve(int l, int r, bool dir) {
  if (l > r) return 0;
  if (vis[l][r][dir]) return f[l][r][dir];
  int fa = dir ? r + 1 : l - 1;
  ll &res = f[l][r][dir] = -1;
  for (int i = l; i <= r; ++i) {
    if (mgcd[i][fa]) {
      if (solve(l, i - 1, 1) != -1 && solve(i + 1, r, 0) != -1)
        max(res, solve(l, i - 1, 1) + solve(i + 1, r, 0) + sum[r] - sum[l - 1]);
    }
  }
  vis[l][r][dir] = true;
  return res;
}

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("testdata.in", "r", stdin);
  freopen("testdata.out", "w", stdout);
#else
  freopen("tree.in", "r", stdin);
  freopen("tree.out", "w", stdout);
#endif
#endif

  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%lld%lld", &a[i].k, &a[i].v);
    if (a[i].k == 1) return puts("-1"), 0;
  }
  std::sort(a + 1, a + n + 1);
  for (int i = 1; i <= n; ++i) {
    mgcd[i][0] = mgcd[0][i] = true;
    for (int j = i + 1; j <= n; ++j)
      if (gcd(a[i].k, a[j].k) != 1) mgcd[i][j] = mgcd[j][i] = true;
  }
  for (int i = 1; i <= n; ++i) { sum[i] = sum[i - 1] + a[i].v; }
  printf("%lld", solve(1, n, 0));
  return 0;
}